package com.maimao.order.client.factory;

import cn.hutool.core.util.StrUtil;
import com.maimao.core.model.resp.Result;
import com.maimao.order.client.GoodsClient;
import feign.hystrix.FallbackFactory;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.tm.api.GlobalTransactionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * @author MaoLin Wang
 * @date 2020/11/30 10:03 下午
 */
@Component
@Slf4j
public class GoodsFallBackFactory implements FallbackFactory<GoodsClient> {

    @Override
    public GoodsClient create(Throwable cause) {
        String errorMsg = cause.getMessage() == null ? "" : cause.getMessage();

        return new GoodsClient() {
            @Override
            /**
             * 在该位置手动回滚，会出现
             */
            public Result<Void> updateStock(Integer oper, Map<Long, Integer> stockMap) {
                StringBuilder sb = new StringBuilder();
                sb.append("调用[GoodsClient-updateStock({},{})]出错 :{}\n");
                boolean globalTc = false;
                if (!StrUtil.isBlank(RootContext.getXID())) {
                    try {
                        GlobalTransactionContext.reload(RootContext.getXID()).rollback();
                        sb.append("执行回滚，xid:{}");
                        globalTc = true;
                    } catch (TransactionException e) {
                        e.printStackTrace();
                        log.error("回滚失败,降级方法:[GoodsClient-updateStock()],xid:{}", RootContext.getXID());
                    }
                }
                if (globalTc) {
                    log.error(sb.toString(), oper, stockMap, errorMsg, RootContext.getXID());
                } else {
                    log.error(sb.toString(), oper, stockMap, errorMsg);
                }

                return Result.fail(errorMsg);
            }

            @Override
            public Result<Void> addSellCount(Map<Long, Integer> sellCountMap) {
                StringBuilder sb = new StringBuilder();
                sb.append("调用[GoodsClient-addSellCount({})]出错 :{}\n");
                boolean globalTc = false;
                if (!StrUtil.isBlank(RootContext.getXID())) {
                    try {
                        GlobalTransactionContext.reload(RootContext.getXID()).rollback();
                        sb.append("执行回滚，xid:{}");
                        globalTc = true;
                    } catch (TransactionException e) {
                        e.printStackTrace();
                        log.error("回滚失败,降级方法:[GoodsClient-addSellCount()],xid:{}", RootContext.getXID());
                    }
                }
                if (globalTc) {
                    log.error(sb.toString(), sellCountMap, errorMsg, RootContext.getXID());
                } else {
                    log.error(sb.toString(), sellCountMap, errorMsg);
                }
                return Result.fail(errorMsg);
            }

            @Override
            public Result<Boolean> checkSkuBatch(Map<Long, Integer> data) {
                log.error("调用[GoodsClient-checkSkuBatch({})]出错 :{}", data, errorMsg);
                return Result.fail(errorMsg);
            }

            @Override
            public Result<Boolean> checkSpuBatch(List<Long> goodsIdList) {
                log.error("调用[GoodsClient-checkSpuBatch({})]出错 :{}", goodsIdList, errorMsg);
                return Result.fail(errorMsg);
            }

            @Override
            public Result<Long> queryBrandIdByGoodsId(Long goodsId) {
                log.error("调用[GoodsClient-queryBrandIdByGoodsId({})]出错 :{}", goodsId, errorMsg);
                return Result.fail(errorMsg);
            }
        };
    }
}
